﻿using System;
using System.Threading;
using System.Collections;
using System.Text;

namespace MonitorCS1
{
    public static class ThreadExt
    {
        public static void WriteLine(this Thread t,string remark,params Thread[] threads)
        {
            DateTime dt = DateTime.Now;
            StringBuilder sb = new StringBuilder();
            foreach (Thread item in threads)
            {
                sb.AppendFormat("[线程名:{0,-5} ID:{1} 状态:{2,-13}]\t", item.Name, item.ManagedThreadId, item.ThreadState);
            }
            Console.WriteLine("{0:HH:mm:ss.fff} {1,-10}\t当前线程名:{2,-5} ID:{3} 状态:{4,-13} {5}",
                dt, remark, t.Name, t.ManagedThreadId,t.ThreadState,sb.ToString());
        }
    }


    class MonitorSample
    {
        const int MAX_LOOP_TIME = 5;
        Queue m_smplQueue;
        private Thread _t1 = null;
        private Thread _t2 = null;

        public MonitorSample()
        {
            m_smplQueue = new Queue();
        }
        public Thread T1 { set { _t1 = value; } }
        public Thread T2 { set { _t2 = value; } }
        public void FirstThread()
        {
            int counter = 0;
            lock (m_smplQueue)
            {
                while (counter < MAX_LOOP_TIME)
                {
                    Thread.CurrentThread.WriteLine("Wait()前", _t1, _t2);
                    Monitor.Wait(m_smplQueue);
                    Thread.CurrentThread.WriteLine("Wait()前", _t1, _t2);

                    m_smplQueue.Enqueue(counter);

                    Thread.CurrentThread.WriteLine("Wait()前", _t1, _t2);
                    //Monitor.Pulse(m_smplQueue);
                    Thread.CurrentThread.WriteLine("Wait()前", _t1, _t2);

                    counter++;
                    //Console.WriteLine("T1-5 Pulse() 后 counter={0}", counter);
                }
            }
        }
        public void SecondThread()
        {
            lock (m_smplQueue)
            {
                Thread.CurrentThread.WriteLine("Pulse()前", _t1, _t2);

                Monitor.Pulse(m_smplQueue);

                Thread.CurrentThread.WriteLine("Pulse()后", _t1, _t2);

                Thread.CurrentThread.WriteLine("Wait()前", _t1, _t2);
                while (Monitor.Wait(m_smplQueue, 1000))
                {
                    Thread.CurrentThread.WriteLine("Wait()后", _t1, _t2);
                    int counter = (int)m_smplQueue.Dequeue();
                    Thread.CurrentThread.WriteLine("Pulse()后", _t1, _t2);
                    Monitor.Pulse(m_smplQueue);
                    Thread.CurrentThread.WriteLine("Pulse()后", _t1, _t2);
                }
            }
        }
        public int GetQueueCount()
        {
            return m_smplQueue.Count;
        }

        private static Thread t = new Thread(new ParameterizedThreadStart(P));
        private static readonly object _syncObj = new Object();

        static void P(object mainObj)
        {
            Thread.CurrentThread.WriteLine("P-1 开始    ", ((Thread)mainObj));
            lock (_syncObj)
            {
                Thread.CurrentThread.WriteLine("P-2 Lock Wait 前 ");
                Monitor.Wait(_syncObj);
            }
            Thread.CurrentThread.WriteLine("P-2 结束    ");
        }

        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Main";
            Thread.CurrentThread.WriteLine("Main-1:开始    ");
            #region 
            //MonitorTest monitorTest = new MonitorTest();
            //Thread t1 = new Thread(new ThreadStart(monitorTest.P1));
            //t1.Name = "P1";

            //Thread t2 = new Thread(new ThreadStart(monitorTest.P2));
            //t2.Name = "P2";

            //t1.Start();
            //t2.Start();
            #endregion

            #region 
            t.Name = "P";
            t.Start(Thread.CurrentThread);

            //Thread.Sleep(100);
            //Thread.CurrentThread.WriteLine("Main Lock 前");
            //t.WriteLine("xxx");
            //lock (count)
            //{
            //    Thread.CurrentThread.WriteLine("Main Lock 中");
            //    //Thread.Sleep(10);
            //    Monitor.Pulse(count);
            //    Thread.CurrentThread.WriteLine("Main Pulse 后");
            //    Thread.Sleep(1000);
            //}

            #endregion

            #region 
            //MonitorSample test = new MonitorSample();
            //Thread tFirst = new Thread(new ThreadStart(test.FirstThread));
            //tFirst.Name = "T1";
            //test.T1 = tFirst;
            //Thread tSecond = new Thread(new ThreadStart(test.SecondThread));
            //tSecond.Name = "T2";
            //test.T2 = tSecond;
            //tFirst.WriteLine("Start()前");
            //tFirst.Start();
            //tFirst.WriteLine("Start()后");
            //tSecond.WriteLine("Start()前");
            //tSecond.Start();
            //tSecond.WriteLine("Start()后");
            //tFirst.WriteLine("Join()前");
            //tFirst.Join();
            //tFirst.WriteLine("Join()后");
            //tSecond.WriteLine("Join()前");
            //tSecond.Join();
            //tSecond.WriteLine("Join()后");
            //Console.WriteLine("Queue Count = " + test.GetQueueCount().ToString());
            #endregion
            Thread.CurrentThread.WriteLine("Main-2 结束   ");
            //Thread.Sleep(5000);
            //Console.ReadKey();
        }
    }
}